home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
sysb091a.zip
/
sysbench
/
src
/
pmb_diskio.c
< prev
next >
Wrap
Text File
|
1996-05-27
|
10KB
|
533 lines
/* diskio.c - disk benchmark
*
* Author: Kai Uwe Rommel <rommel@ars.muc.de>
* Created: Fri Jul 08 1994
*/
// modified 1994-08-10 by Henrik Harmsen
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define INCL_DOS
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_DOSERRORS
//#define INCL_NOPM
#include <os2.h>
#include "diskacc2.h"
#define INTERVAL 10
int nHandle;
unsigned nSides, nTracks, nSectors;
char *pBuffer;
int time_over;
double dhry_time, dhry_result;
extern unsigned long Number_Of_Runs;
extern long dhry_stone(void);
extern void err(char* s);
int bench_dhry(void);
VOID APIENTRY timer_thread(ULONG nArg)
{
#if 1
HEV hSem;
HTIMER hTimer;
DosCreateEventSem(0, &hSem, DC_SEM_SHARED, 0);
DosAsyncTimer(nArg * 1000, (HSEM) hSem, &hTimer);
DosWaitEventSem(hSem, SEM_INDEFINITE_WAIT);
DosStopTimer(hTimer);
DosCloseEventSem(hSem);
#else
DosSleep(nArg * 1000);
#endif
time_over = 1;
Number_Of_Runs = 0;
DosExit(EXIT_THREAD, 0);
}
int start_alarm(ULONG nSeconds)
{
TID ttid;
time_over = 0;
Number_Of_Runs = -1;
if (DosCreateThread(&ttid, timer_thread, nSeconds, 0, 8192))
{
err("Cannot create timer thread");
return -1;
}
return 0;
}
int start_timer(QWORD *nStart)
{
if (DosTmrQueryTime(nStart))
{
err("Timer error");
return -1;
}
return 0;
}
int stop_timer(QWORD *nStart, int accuracy)
{
QWORD nStop;
ULONG nFreq;
if (DosTmrQueryTime(&nStop))
{
err("Timer error 2");
return -1;
}
if (DosTmrQueryFreq(&nFreq))
{
err("Timer error 3");
return -1;
}
nFreq = (nFreq + accuracy / 2) / accuracy;
return (nStop.ulLo - nStart->ulLo) / nFreq;
}
int bench_transfer(int nTrack, int nDirection)
{
int nCnt, nData = 0, nTime, Dxfer;
QWORD nLocal;
//printf("Data transfer rate on track %-4d: ", nTrack);
//fflush(stdout);
if (start_alarm(INTERVAL))
return -1;
if (start_timer(&nLocal))
return -1;
for (nCnt = 0; !time_over; nCnt++)
{
if (DskRead(nHandle, nCnt % nSides, nTrack + (nCnt / nSides) * nDirection, 1, nSectors, pBuffer))
{
err("Disk read error - bench transfer.");
return -1;
}
nData += nSectors * 512;
}
if ((nTime = stop_timer(&nLocal, 1024)) == -1)
return -1;
Dxfer = nData / nTime;
return Dxfer;
}
int bench_bus(void)
{
int nCnt, nData = 0, nTime, Dxfer;
QWORD nLocal;
//printf("Drive cache/bus transfer rate: ");
//fflush(stdout);
if (start_alarm(INTERVAL))
return -1;
if (start_timer(&nLocal))
return -1;
for (nCnt = 0; !time_over; nCnt++)
{
if (DskRead(nHandle, 0, 0, 1, nSectors, pBuffer))
{
err("Disk read error - bus/cache.");
return -1;
}
nData += nSectors * 512;
}
if ((nTime = stop_timer(&nLocal, 1024)) == -1)
return -1;
Dxfer = nData / nTime;
return Dxfer;
}
int bench_latency(void)
{
int nCnt, nSector, nTime;
QWORD nLocal;
//printf("Average latency time: ");
//fflush(stdout);
srand(1);
if (start_alarm(INTERVAL))
return -1;
if (start_timer(&nLocal))
return -1;
for (nCnt = 0; !time_over; nCnt++)
{
nSector = rand() * nSectors / RAND_MAX + 1;
if (DskRead(nHandle, 0, 0, nSector, 1, pBuffer))
{
err("Disk read error - bench latency.");
return -1;
}
}
if ((nTime = stop_timer(&nLocal, 1000)) == -1)
return -1;
nTime = nTime * 10 / nCnt;
//printf("%d.%d ms\n", nTime / 10, nTime % 10);
return nTime;
}
int bench_seek(void)
{
int nCnt, nTrack, nTime;
QWORD nLocal;
//printf("Average data access time: ");
//fflush(stdout);
srand(1);
if (start_alarm(INTERVAL))
return -1;
if (start_timer(&nLocal))
return -1;
for (nCnt = 0; !time_over; nCnt++)
{
nTrack = rand() * nTracks / RAND_MAX;
if (DskRead(nHandle, 0, nTrack, 1, 1, pBuffer))
{
err("Disk read error - bench seek.");
return -1;
}
}
if ((nTime = stop_timer(&nLocal, 1000)) == -1)
return -1;
nTime = nTime * 10 / nCnt;
//printf("%d.%d ms\n", nTime / 10, nTime % 10);
return nTime;
}
VOID APIENTRY dhry_thread(ULONG nArg)
{
APIRET rc;
rc = DosSetPriority(PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MAXIMUM, 0);
dhry_time = dhry_stone();
DosExit(EXIT_THREAD, 0);
}
double bench_concurrent(void)
{
int nCnt, nData = 0, nTime;
double percent;
QWORD nLocal;
TID dtid;
APIRET rc;
if (start_alarm(INTERVAL))
return -1;
if (DosCreateThread(&dtid, dhry_thread, 0, 0, 8192))
return -1;
if (start_timer(&nLocal))
return -1;
for (nCnt = 0; !time_over; nCnt++)
{
if (DskRead(nHandle, 0, 0, 1, nSectors, pBuffer))
{
err("Disk read error - concurrency test.");
return -1;
}
nData += nSectors * 512;
}
if ((nTime = stop_timer(&nLocal, 1024)) == -1)
return -1;
if ((rc = DosWaitThread(&dtid, DCWW_WAIT)) && rc != ERROR_INVALID_THREADID)
return -1; /* it may have already terminated */
dhry_time = (dhry_time + 500) / 1000;
percent = ((dhry_result-(Number_Of_Runs / dhry_time)) * 100 / dhry_result);
return percent;
}
int bench_disk(int nDisk)
{
char szName[8];
sprintf(szName, "$%d:", nDisk);
if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
{
err("Cannot access disk");
return -1;
}
// printf("\nDisk %d: %d sides, %d cylinders, %d sectors per track = %d MB\n", nDisk, nSides, nTracks, nSectors, nSides * nTracks * nSectors / 2048);
if ((pBuffer = malloc(nSectors * 512)) == NULL)
{
err("Not enough memory - bench disk.");
return -1;
}
bench_bus();
bench_transfer(0, 1);
bench_transfer(nTracks - 1, -1);
// bench_concurrent();
bench_latency();
bench_seek();
free(pBuffer);
DskClose(nHandle);
return 0;
}
static double bench_disk_avseek(int nDisk)
{
char szName[8];
double r;
sprintf(szName, "$%d:", nDisk);
if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0) {
err("Disk IO test error : Cannot access disk - avseek.");
exit(1);
}
if ((pBuffer = malloc(nSectors * 512)) == NULL) {
err("Disk IO test error : malloc() failed.");
exit(1);
}
r = bench_seek();
free(pBuffer);
DskClose(nHandle);
return r;
}
static double bench_disk_transfer(int nDisk)
{
char szName[8];
double r;
sprintf(szName, "$%d:", nDisk);
if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0) {
err("Disk IO test error : Cannot access disk - bench disk xfer.");
exit(1);
}
if ((pBuffer = malloc(nSectors * 512)) == NULL) {
err("Disk IO test error : malloc() failed.");
exit(1);
}
r = (bench_transfer(nTracks-1, -1)+bench_transfer(0, 1)+bench_transfer(nTracks/2, 1))/3;
free(pBuffer);
DskClose(nHandle);
return r;
}
double pmb_diskio_avseek(int disknr)
{
double r;
disknr++;
// DosCreateEventSem(NULL, &hSemTimer, DC_SEM_SHARED, 0);
// DosSleep(500);
r = bench_disk_avseek(disknr);
// DosCloseEventSem(hSemTimer);
// hSemTimer = 0;
return r;
}
double pmb_buscache_xfer(int disknr)
{
double r;
char szName[8];
disknr++;
sprintf(szName, "$%d:", disknr);
if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
{
err("Cannot access disk");
return -1;
}
if ((pBuffer = malloc(nSectors * 512)) == NULL)
{
err("Not enough memory - bus cache test.");
return -1;
}
r = bench_bus();
free(pBuffer);
DskClose(nHandle);
return r;
}
double pmb_diskio_transfer(int disknr)
{
double r;
disknr++;
r = bench_disk_transfer(disknr);
return r;
}
double